package models

import (
	"errors"
	"github.com/beego/beego/v2/core/logs"
	"gorm.io/gorm/clause"
	"strings"
	"time"
)

// AdminRole 角色模型
type AdminRole struct {
	Id        uint        `json:"id"`
	Name      string      `json:"name"`
	Slug      string      `json:"slug"`
	Menus     []AdminMenu `json:"menus" gorm:"many2many:admin_role_menu"`
	CreatedAt time.Time   `json:"created_at"`
	UpdatedAt time.Time   `json:"updated_at"`
}

// @title 数据校验
func (a *AdminRole) validate() error {
	if a.Name == "" {
		return errors.New("角色名称不能为空")
	}

	if a.Slug == "" {
		return errors.New("角色标识不能为空")
	}

	var count int64
	Db.Model(a).Where("slug = ?", a.Slug).Where("id <> ?", a.Id).Count(&count)

	if count > 0 {
		return errors.New("角色标识已存在")
	}

	return nil
}

// @title 添加
func (a *AdminRole) Store() error {
	err := a.validate()

	if err != nil {
		return err
	}

	a.Id = 0

	res := Db.Omit(clause.Associations).Create(a)

	a.handleAssociations()

	return res.Error
}

// @title 获取列表
func (a *AdminRole) GetList(page, pageSize int) ([]map[string]interface{}, int64) {
	var list []AdminRole
	var total int64

	Db.Model(a).Count(&total)
	Db.Limit(pageSize).Offset((page - 1) * pageSize).Order("updated_at desc").Find(&list)

	data := DateTimeFormatList(list, []string{"created_at", "updated_at"})

	return data, total
}

// @title 获取单条数据
func (a *AdminRole) GetOne(id string) AdminRole {
	var data AdminRole

	Db.Model(a).Preload("Menus").Where("id = ?", id).First(&data)

	return data
}

// @title 更新
func (a *AdminRole) Update() error {
	err := a.validate()

	if err != nil {
		return err
	}

	a.handleAssociations()

	return Db.Omit(clause.Associations).Save(a).Error
}

// @title 处理关联关系
func (a *AdminRole) handleAssociations() {
	var roleMenu []map[string]interface{}

	for _, item := range a.Menus {
		roleMenu = append(roleMenu, map[string]interface{}{
			"admin_role_id": a.Id,
			"admin_menu_id": item.Id,
		})
	}

	Db.Table("admin_role_menu").Where("admin_role_id = ?", a.Id).Delete(nil)

	if len(roleMenu) > 0 {
		Db.Table("admin_role_menu").Create(roleMenu)
	}
}

// @title 删除
func (a *AdminRole) Delete(ids string) error {
	res := Db.Delete(AdminRole{}, "id in (?)", strings.Split(ids, ","))

	// 删除关联关系
	Db.Table("admin_role_menu").Where("admin_role_id in (?)", strings.Split(ids, ",")).Delete(nil)

	if res.Error != nil {
		logs.Error(res.Error.Error())
		return res.Error
	}

	return nil
}

// @title 获取选项
func (a *AdminRole) GetOptions() []map[string]interface{} {
	var list []AdminRole

	Db.Model(a).Find(&list)

	var options []map[string]interface{}

	for _, item := range list {
		options = append(options, map[string]interface{}{
			"value": item.Id,
			"label": item.Name,
		})
	}

	return options
}
